package ink.ykb.actDemo.service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.beetl.sql.core.query.LambdaQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ink.ykb.actDemo.controller.vo.UserTask;
import ink.ykb.actDemo.dao.LeaveDao;
import ink.ykb.actDemo.dao.UserInfoDao;
import ink.ykb.actDemo.entity.Leave;
import ink.ykb.actDemo.entity.UserInfo;
import ink.ykb.actDemo.util.HttpRequestLocal;
import ink.ykb.actDemo.util.PlatformRuntimeException;
import ink.ykb.actDemo.util.bean.LeaveState;

@Service
@Transactional
public class LeaveService {
	
	@Autowired
	private WorkflowService workflowService;
	@Autowired
	private HttpRequestLocal httpRequestLocal;

	@Autowired
	private LeaveDao leaveDao;
	@Autowired
	private UserInfoDao userInfoDao;
	
	/**
	 * 保存请假信息
	 * @param leave
	 */
	public void save(Leave leave) {
		
		Integer uid = httpRequestLocal.getUserId();
		UserInfo user = this.userInfoDao.single(uid);
		leave.setUid(user.getId());
		leave.setName(user.getName());
		leave.setState(LeaveState.CREATE.getId());
		leaveDao.insert(leave);
	}
	/**
	 * 保存请假信息
	 * @param leave
	 */
	public List<Leave> getLeaveList() {
		
		Integer uid = httpRequestLocal.getUserId();
		 List<Leave> list = leaveDao.createLambdaQuery().andEq(Leave::getUid, uid).select();
		return list;
	}
	/**
	 * 部署流程
	 */
	public void deploy() {
		workflowService.deploy("/leaveProcess.bpmn","leave");
	}

	/**
	 * 获取任务列表
	 * @param leaveId
	 * @return
	 */
	public List<UserTask> getUserTask(Integer leaveId){
		
		Integer uid = httpRequestLocal.getUserId();
		Leave leave = this.leaveDao.single(leaveId);
		if(leave == null) {throw new PlatformRuntimeException("查询不到该请假申请");}
		
		List<Task> tasks = workflowService.findTaskListByAssignee(uid.toString(),leave.getInstaceId());
		       
        List<UserTask> list = new ArrayList<>();
        if(tasks != null && tasks.size() > 0) {
        	for(Task task : tasks){
                UserTask t = new UserTask();
                t.setTaskId(task.getId());
                t.setName(task.getName());
                t.setAssignee(task.getAssignee());
                t.setExecutionId(task.getExecutionId());
                t.setProcessInstanceId(task.getProcessInstanceId());
                t.setProcessDefinitionId(task.getProcessDefinitionId());
                list.add(t);
            }
        }
        return list;
	}
	/**
	 * 显示流程图
	 * @param processInstanceId
	 * @param response
	 */
    public void showImg(HttpServletResponse response,String leaveId){  
        try {  
		    	Leave leave = this.leaveDao.single(leaveId);
		    	if(leave != null && leave.getInstaceId() !=null) {
			        InputStream pic = workflowService.getResourceDiagramInputStream(leave.getInstaceId());
			        
			        byte[] b = new byte[1024];  
			        int len = -1;  
			        while((len = pic.read(b, 0, 1024)) != -1) {  
			            response.getOutputStream().write(b, 0, len);  
			        }  
			        pic.close();
		    	}else {
		    		response.getWriter().write("");
		    	}
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }
    
    /**
     * 提交请假申请
     * @param leaveId
     */
	public void applyLeave(Integer leaveId) {
		Integer uid = httpRequestLocal.getUserId();
    	Leave leave = this.leaveDao.single(leaveId);
		if(leave == null) {throw new PlatformRuntimeException("查询不到该请假申请");}
		if(!uid.equals(leave.getUid())) {throw new PlatformRuntimeException("只能提交自己的请假申请");}
		if(!leave.getState().equals(LeaveState.CREATE.getId())) {throw new PlatformRuntimeException("请假申请已存在，请勿重复提交");}
		
		//初始化变量
		Map<String, Object> map = new HashMap<>();
        map.put("day", leave.getDays());
        map.put("leaveId", leave.getId());
        
		//创建请假申请任务
		ProcessInstance pi = workflowService.startProcessInstanceByKey("leaveProcess",map);
		leave.setInstaceId(pi.getId());
		leave.setProcessDefinitionId(pi.getProcessDefinitionId());
		leave.setState(LeaveState.REVIEW.getId());
		
		this.leaveDao.updateById(leave);
		
		//提交请假任务
	    Task task = workflowService.findTaskByAssignee(leave.getUid().toString(),leave.getInstaceId());
	    
        Map<String, Object> varMap = new HashMap<>();
        varMap.put("cancle", false);
        varMap.put("pass", true);
	    workflowService.completeTask(task.getId(), varMap);
		
	}
	/**
	 * 取消请假申请
	 * @param leaveId
	 */
	public void cancleLeave(Integer leaveId) {
		Integer uid = httpRequestLocal.getUserId();
    	Leave leave = this.leaveDao.single(leaveId);
		if(leave == null) {throw new PlatformRuntimeException("查询不到该请假申请");}
		if(!uid.equals(leave.getUid())) {throw new PlatformRuntimeException("只能取消自己的请假申请");}
		if(!leave.getState().equals(LeaveState.REJECT.getId())) {throw new PlatformRuntimeException("只能在申请被驳回后才能取消申请");}
		
		leave.setState(LeaveState.CANCEL.getId());
		this.leaveDao.updateById(leave);
		
		//取消申请任务
		Task task = workflowService.findTaskByAssignee(leave.getUid().toString(),leave.getInstaceId());
	    
	    Map<String, Object> map = new HashMap<>();
	    map.put("cancle", true);
        
	    workflowService.completeTask(task.getId(), map);
	}
	
	
    /**
     * 审批
     */
    public  void review(Integer leaveId,String taskId,Boolean passLeave,String cause) {
        	Integer uid = httpRequestLocal.getUserId();
        	Leave leave = this.leaveDao.single(leaveId);
    		if(leave == null) {throw new PlatformRuntimeException("查询不到该请假申请");}
    		if(passLeave == null) {throw new PlatformRuntimeException("审批参数不能为空");}
    		if(!passLeave && cause == null) {throw new PlatformRuntimeException("审批不通过原因不能为空");}
    	    
    		Task task = null;
    	    if(taskId != null) {
    	    	 List<Task> tasks = workflowService.findTaskListByAssignee(uid.toString(),leave.getInstaceId());
    	    	 if(tasks == null || tasks.size()== 0) {throw new PlatformRuntimeException("未查询任何任务");} 
    	    	 for (Task t : tasks) {
    				if(t.getId().equals(taskId)) {
    					task = t;
    					break;
    				}
    			 }
    	    }else {
    	    	 task = workflowService.findTaskByAssignee(uid.toString(),leave.getInstaceId());
    	    }
    	    if(task == null) {throw new PlatformRuntimeException("未查询任何任务");} 
    	    
    	    if(!passLeave) {//不通过，设置审批状态为驳回
    	    	leave.setState(LeaveState.REJECT.getId());
    	    	this.leaveDao.updateById(leave);
    	    }
    	    
    	    
    	    Map<String, Object> map = new HashMap<>();
    	    map.put("pass", passLeave);
    	    map.put("cause", cause);
	    	workflowService.completeTask(task.getId(),map);
    	    
    }

   
}
